package com.zxy.leetcode._01100_01199._01110_01119;

public class Test01115 {
    public static void main(String[] args) {
        Runnable printFoo = () -> System.out.println("foo");
        Runnable printBar = () -> System.out.println("bar");

        FooBar fooBar = new FooBar(3);
        new Thread(() -> {
            try {
                fooBar.foo(printFoo);
            } catch (InterruptedException e) {
            }
        }).start();

        new Thread(() -> {
            try {
                fooBar.bar(printBar);
            } catch (InterruptedException e) {
            }
        }).start();
    }
}

class FooBar {
    private int n;
    private Object lock = new Object();
    private boolean fooOrBar = true;    // true则foo，false则bar

    public FooBar(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws InterruptedException {

        for (int i = 0; i < n; i++) {
            synchronized (lock) {
                while (!fooOrBar) {
                    lock.wait();
                }
                // printFoo.run() outputs "foo". Do not change or remove this line.
                printFoo.run();
                fooOrBar = false;
                lock.notifyAll();
            }
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {

        for (int i = 0; i < n; i++) {
            synchronized (lock) {
                while (fooOrBar) {
                    lock.wait();
                }
                // printBar.run() outputs "bar". Do not change or remove this line.
                printBar.run();
                fooOrBar = true;
                lock.notifyAll();
            }
        }
    }
}
